/**
 * @file test_debug_mapping.cpp
 * @brief 测试字节码到源代码行号的映射功能
 * @author VimLVM Team
 * @date 2025
 */

#include <gtest/gtest.h>
#include "viml/compiler.h"
#include "viml/vm.h"

using namespace viml;

/**
 * @brief 测试基本行号映射
 */
TEST(DebugMappingTest, BasicLineMapping) {
    std::string source = R"(
let x = 10
let y = 20
let z = x + y
echo z
)";
    
    Compiler compiler;
    auto result = compiler.compile(source, "test.vim");
    
    ASSERT_TRUE(result.success);
    ASSERT_NE(result.function, nullptr);
    ASSERT_NE(result.function->debug_info, nullptr);
    
    // 验证行号映射存在
    const auto& debug_info = result.function->debug_info;
    EXPECT_GT(debug_info->line_map.size(), 0);
    
    // 验证第2行(let x = 10)有对应的字节码
    size_t line2_offset = debug_info->get_offset_for_line(2);
    EXPECT_GT(line2_offset, 0);
    
    // 验证第3行(let y = 20)有对应的字节码
    size_t line3_offset = debug_info->get_offset_for_line(3);
    EXPECT_GT(line3_offset, line2_offset);
}

/**
 * @brief 测试条件语句的行号映射
 */
TEST(DebugMappingTest, ConditionalLineMapping) {
    std::string source = R"(
let x = 10
if x > 5
    let y = 20
else
    let y = 30
endif
echo y
)";
    
    Compiler compiler;
    auto result = compiler.compile(source, "test.vim");
    
    ASSERT_TRUE(result.success);
    ASSERT_NE(result.function, nullptr);
    ASSERT_NE(result.function->debug_info, nullptr);
    
    // 验证所有关键行都有映射
    const auto& debug_info = result.function->debug_info;
    
    EXPECT_GT(debug_info->get_offset_for_line(2), 0); // let x = 10
    EXPECT_GT(debug_info->get_offset_for_line(3), 0); // if x > 5
    EXPECT_GT(debug_info->get_offset_for_line(4), 0); // let y = 20
    EXPECT_GT(debug_info->get_offset_for_line(6), 0); // let y = 30
    EXPECT_GT(debug_info->get_offset_for_line(8), 0); // echo y
}

/**
 * @brief 测试循环语句的行号映射
 */
TEST(DebugMappingTest, LoopLineMapping) {
    std::string source = R"(
let i = 0
while i < 3
    let i = i + 1
endwhile
echo i
)";
    
    Compiler compiler;
    auto result = compiler.compile(source, "test.vim");
    
    ASSERT_TRUE(result.success);
    ASSERT_NE(result.function, nullptr);
    ASSERT_NE(result.function->debug_info, nullptr);
    
    // 验证循环结构的行号映射
    const auto& debug_info = result.function->debug_info;
    
    EXPECT_GT(debug_info->get_offset_for_line(2), 0); // let i = 0
    EXPECT_GT(debug_info->get_offset_for_line(3), 0); // while i < 3
    EXPECT_GT(debug_info->get_offset_for_line(4), 0); // let i = i + 1
    EXPECT_GT(debug_info->get_offset_for_line(6), 0); // echo i
}

/**
 * @brief 测试变量映射
 */
TEST(DebugMappingTest, VariableMapping) {
    std::string source = R"(
let x = 10
let y = x + 5
)";
    
    Compiler compiler;
    auto result = compiler.compile(source, "test.vim");
    
    ASSERT_TRUE(result.success);
    ASSERT_NE(result.function, nullptr);
    ASSERT_NE(result.function->debug_info, nullptr);
    
    // 验证变量映射
    const auto& debug_info = result.function->debug_info;
    
    EXPECT_GT(debug_info->get_offset_for_variable("x"), 0);
    EXPECT_GT(debug_info->get_offset_for_variable("y"), 0);
}

/**
 * @brief 测试空程序的行号映射
 */
TEST(DebugMappingTest, EmptyProgramMapping) {
    std::string source = R"(
" 这是一个注释
" 只有注释的程序
)";
    
    Compiler compiler;
    auto result = compiler.compile(source, "test.vim");
    
    ASSERT_TRUE(result.success);
    ASSERT_NE(result.function, nullptr);
    ASSERT_NE(result.function->debug_info, nullptr);
    
    // 空程序应该有基本的映射
    const auto& debug_info = result.function->debug_info;
    EXPECT_GE(debug_info->line_map.size(), 0);
}